package com.onesports.intelligent.k12.polarlight.service.common;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.onesports.framework.kit.common.util.ParamUtils;
import com.onesports.intelligent.k12.polarlight.common.domain.entity.BaseEntity;
import com.onesports.intelligent.k12.polarlight.constant.CacheConstants;
import com.onesports.intelligent.k12.polarlight.domain.entity.course.ClassInfo;
import com.onesports.intelligent.k12.polarlight.domain.entity.course.Course;
import com.onesports.intelligent.k12.polarlight.domain.entity.organization.Coach;
import com.onesports.intelligent.k12.polarlight.domain.entity.organization.OrganizationCampus;
import com.onesports.intelligent.k12.polarlight.domain.entity.organization.OrganizationStaff;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.Area;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.Dict;
import com.onesports.intelligent.k12.polarlight.domain.vo.common.LocationVO;
import com.onesports.intelligent.k12.polarlight.mapper.course.ClassInfoMapper;
import com.onesports.intelligent.k12.polarlight.mapper.course.CourseMapper;
import com.onesports.intelligent.k12.polarlight.mapper.organization.CoachMapper;
import com.onesports.intelligent.k12.polarlight.mapper.organization.OrganizationCampusMapper;
import com.onesports.intelligent.k12.polarlight.mapper.organization.OrganizationStaffMapper;
import com.onesports.intelligent.k12.polarlight.mapper.sys.AreaMapper;
import com.onesports.intelligent.k12.polarlight.mapper.sys.DictMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zengzl
 */
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = CacheConstants.LOCATION, keyGenerator = "customCacheKeyGenerator")
public class CommonService {
    private final AreaMapper areaMapper;
    private final CoachMapper coachMapper;
    private final OrganizationStaffMapper organizationStaffMapper;
    private final CourseMapper courseMapper;
    private final OrganizationCampusMapper organizationCampusMapper;
    private final ClassInfoMapper classInfoMapper;
    private final DictMapper dictMapper;



    /**
     * 获取省市区
     *
     * @return List<LocationVO>
     */
    @Cacheable
    public List<LocationVO> getLocation() {
        //获取所有的省份
        List<Area> provinceList = this.areaMapper.selectList(new LambdaQueryWrapper<Area>().eq(Area::getRegionLevel, "1").orderByAsc(Area::getSort));
        //获取所有的市并根据省份code分组
        Map<String, List<Area>> cityMap = this.areaMapper.selectList(new LambdaQueryWrapper<Area>()
                .eq(Area::getRegionLevel, "2").orderByAsc(Area::getSort)).stream().collect(Collectors.groupingBy(Area::getParentRegionCode));
        //获取所有的区域并根据市code分组
        Map<String, List<Area>> areaMap = this.areaMapper.selectList(new LambdaQueryWrapper<Area>()
                .eq(Area::getRegionLevel, "3").orderByAsc(Area::getSort)).stream().collect(Collectors.groupingBy(Area::getParentRegionCode));
        return provinceList.stream().map(i -> {
            List<Area> areaList = cityMap.get(i.getRegionCode());
            if (ParamUtils.isNotEmpty(areaList)) {
                List<LocationVO> children = areaList.stream()
                        .map(city -> {
                            List<LocationVO> areas = Optional.ofNullable(areaMap.get(city.getRegionCode()))
                                    .orElse(new ArrayList<>()).stream()
                                    .map(item -> LocationVO.builder().label(item.getRegionName()).code(item.getRegionCode()).build())
                                    .collect(Collectors.toList());
                            return LocationVO.builder().label(city.getRegionName()).code(city.getRegionCode()).children(areas).build();
                        }).collect(Collectors.toList());
                return LocationVO.builder().label(i.getRegionName()).code(i.getRegionCode()).children(children).build();
            }
            return null;
        }).collect(Collectors.toList());
    }


    /**
     * 教练map
     *
     * @return Map<String, String>
     */
    public Map<String, String> coachMap() {
        Map<String, String> map = null;
        List<Coach> coaches = this.coachMapper.selectList(null);
        if (ParamUtils.isNotEmpty(coaches)) {
            List<String> organizationStaffId = coaches.stream().map(Coach::getOrganizationStaffId).collect(Collectors.toList());
            Map<String, String> staffMap = this.organizationStaffMapper.selectBatchIds(organizationStaffId)
                    .stream().collect(Collectors.toMap(BaseEntity::getId, OrganizationStaff::getStaffName));
            coaches.forEach(i -> i.setCoachName(staffMap.get(i.getOrganizationStaffId())));
            map = coaches.stream().filter(f -> ParamUtils.isNotEmpty(f.getCoachName())).collect(Collectors.toMap(BaseEntity::getId, Coach::getCoachName));
        }
        return map;
    }


    /**
     * 获取课程map
     *
     * @return Map<String, String>
     */
    public Map<String, String> courseMap() {
        return Optional.ofNullable(this.courseMapper.selectList(null))
                .orElse(new ArrayList<>())
                .stream().collect(Collectors.toMap(BaseEntity::getId, Course::getCourseName));
    }


    /**
     * 获取校区map
     *
     * @return Map<String, String>
     */
    public Map<String, String> campusMap() {
        return Optional.ofNullable(this.organizationCampusMapper.selectList(null))
                .orElse(new ArrayList<>())
                .stream().collect(Collectors.toMap(BaseEntity::getId, OrganizationCampus::getCampusName));

    }


    /**
     * 班级map
     *
     * @return Map<String, String>
     */
    public Map<String, String> classMap() {
        return Optional.ofNullable(this.classInfoMapper.selectList(null))
                .orElse(new ArrayList<>())
                .stream()
                .collect(Collectors.toMap(BaseEntity::getId, ClassInfo::getClassName));
    }

    /**
     * 根据编码获取省市区
     *
     * @param regionCode 区域编码
     * @return 省市区名称
     */
    public HashMap<String, String> getLocationByCode(List<String> regionCode) {
        HashMap<String, String> hashMap = new HashMap<>(3);

        for (String s : regionCode) {
            Area area = this.areaMapper.selectOne(new LambdaQueryWrapper<Area>()
                    .eq(Area::getRegionCode, s));
            if (ParamUtils.isNotEmpty(area)) {
                hashMap.put(s, area.getRegionName());
            }
        }
        return hashMap;
    }

    public Map<String, String> weekMap(String pid) {
        List<Dict> dictList = this.dictMapper.findDictByPid(pid);
        return dictList.stream().collect(Collectors.toMap(Dict::getCode, Dict::getName));
    }
}
